﻿using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace BrettM.Restful.SDK
{
    /// <summary>
    /// Allows you to define which HTTP verbs are permitted when determining 
    /// whether an HTTP request matches a route. This implementation supports both 
    /// native HTTP verbs and the X-HTTP-Method-Override hidden element
    /// submitted as part of an HTTP POST
    /// </summary>
    public class HttpVerbConstraint : IRouteConstraint
    {

        private HttpVerbs verbs;

        public HttpVerbConstraint(HttpVerbs routeVerbs)
        {
            this.verbs = routeVerbs;
        }

        public bool Match(HttpContextBase httpContext, Route route, string parameterName,
          RouteValueDictionary values, RouteDirection routeDirection)
        {
            switch (httpContext.Request.HttpMethod)
            {
                case "DELETE":
                    return ((verbs & HttpVerbs.Delete) == HttpVerbs.Delete);
                case "PUT":
                    return ((verbs & HttpVerbs.Put) == HttpVerbs.Put);
                case "GET":
                    return ((verbs & HttpVerbs.Get) == HttpVerbs.Get);
                case "HEAD":
                    return ((verbs & HttpVerbs.Head) == HttpVerbs.Head);
                case "POST":

                    // First, check whether it's a real post.
                    if ((verbs & HttpVerbs.Post) == HttpVerbs.Post) return (true);

                    // If not, check for special magic HttpMethodOverride hidden fields.
                    switch (httpContext.Request.Form["X-HTTP-Method-Override"])
                    {
                        case "DELETE":
                            return ((verbs & HttpVerbs.Delete) == HttpVerbs.Delete);
                        case "PUT":
                            return ((verbs & HttpVerbs.Put) == HttpVerbs.Put);
                    }
                    break;
            }
            return (false);
        }
    }
}
